﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace MvcDependency.Internal
{
    /// <summary>
    /// A helpful equality comparer where you pass a Func used to extract the values to compare with
    /// </summary>
    /// <typeparam name="T">The type of objects to compare</typeparam>
    /// <example>
    /// <code>
    ///      var users = new List&lt;User&gt; { new User { EmployeeNumber = "1234" }, new User { EmployeeNumber = "1234" } };
    ///      users.Distinct(new FuncEqualityComparer&lt;User&gt;(u => u.EmployeeNumber));
    /// </code>
    /// </example>
    internal class FuncEqualityComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T, object>[] _keyExtractors;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="keyExtractors">The function to use in extracting the keys during comparison</param>
        public FuncEqualityComparer(params Func<T, object>[] keyExtractors)
        {
            _keyExtractors = keyExtractors;
        }

        #region IEqualityComparer<T> Members

        public bool Equals(T x, T y)
        {
            return _keyExtractors.All(keyExtractor => keyExtractor(x).Equals(keyExtractor(y)));
        }

        public int GetHashCode(T obj)
        {
            return _keyExtractors.Aggregate(0, (x, y) => x & y(obj).GetHashCode());
        }

        #endregion
    }
}